package handler

import (
	"encoding/json"
	"io"
	"net/http"

	"backend/database"

	"gorm.io/gorm"
)

// TagRequest 标签请求结构
type TagRequest struct {
	Name string `json:"name"`
}

// ListTags 获取标签列表
func (h *Handler) ListTags(w http.ResponseWriter, r *http.Request) {
	var tags []database.Tag

	// 获取所有标签
	result := h.DB.Find(&tags)
	if result.Error != nil {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	respondWithJSON(w, http.StatusOK, tags)
}

// GetTag 获取单个标签
func (h *Handler) GetTag(w http.ResponseWriter, r *http.Request) {
	id := GetPathParam(r, "id")
	var tag database.Tag

	// 获取标签详情，包括关联的知识条目
	result := h.DB.Preload("Knowledges").First(&tag, id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			respondWithError(w, http.StatusNotFound, "Tag not found")
			return
		}
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	respondWithJSON(w, http.StatusOK, tag)
}

// CreateTag 创建标签
func (h *Handler) CreateTag(w http.ResponseWriter, r *http.Request) {
	var req TagRequest
	body, err := io.ReadAll(r.Body)
	if err != nil {
		respondWithError(w, http.StatusBadRequest, "Invalid request body")
		return
	}
	defer r.Body.Close()

	if err := json.Unmarshal(body, &req); err != nil {
		respondWithError(w, http.StatusBadRequest, err.Error())
		return
	}

	// 验证必填字段
	if req.Name == "" {
		respondWithError(w, http.StatusBadRequest, "Name is required")
		return
	}

	// 检查标签名是否已存在
	var existingTag database.Tag
	result := h.DB.Where("name = ?", req.Name).First(&existingTag)
	if result.Error == nil {
		respondWithError(w, http.StatusBadRequest, "Tag name already exists")
		return
	} else if result.Error != gorm.ErrRecordNotFound {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	// 创建标签
	tag := database.Tag{
		Name: req.Name,
	}

	result = h.DB.Create(&tag)
	if result.Error != nil {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	respondWithJSON(w, http.StatusCreated, tag)
}

// UpdateTag 更新标签
func (h *Handler) UpdateTag(w http.ResponseWriter, r *http.Request) {
	id := GetPathParam(r, "id")
	var req TagRequest
	body, err := io.ReadAll(r.Body)
	if err != nil {
		respondWithError(w, http.StatusBadRequest, "Invalid request body")
		return
	}
	defer r.Body.Close()

	if err := json.Unmarshal(body, &req); err != nil {
		respondWithError(w, http.StatusBadRequest, err.Error())
		return
	}

	// 验证必填字段
	if req.Name == "" {
		respondWithError(w, http.StatusBadRequest, "Name is required")
		return
	}

	// 检查标签是否存在
	var tag database.Tag
	result := h.DB.First(&tag, id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			respondWithError(w, http.StatusNotFound, "Tag not found")
			return
		}
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	// 检查新标签名是否与其他标签重复
	var existingTag database.Tag
	result = h.DB.Where("name = ? AND id != ?", req.Name, id).First(&existingTag)
	if result.Error == nil {
		respondWithError(w, http.StatusBadRequest, "Tag name already exists")
		return
	} else if result.Error != gorm.ErrRecordNotFound {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	// 更新标签
	tag.Name = req.Name

	result = h.DB.Save(&tag)
	if result.Error != nil {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	respondWithJSON(w, http.StatusOK, tag)
}

// DeleteTag 删除标签
func (h *Handler) DeleteTag(w http.ResponseWriter, r *http.Request) {
	id := GetPathParam(r, "id")

	// 检查标签是否存在
	var tag database.Tag
	result := h.DB.First(&tag, id)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			respondWithError(w, http.StatusNotFound, "Tag not found")
			return
		}
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	// 检查标签是否被知识条目引用
	count := h.DB.Model(&tag).Association("Knowledges").Count()

	if count > 0 {
		respondWithError(w, http.StatusBadRequest, "Tag is being used by knowledge entries")
		return
	}

	// 删除标签
	result = h.DB.Delete(&tag)
	if result.Error != nil {
		respondWithError(w, http.StatusInternalServerError, result.Error.Error())
		return
	}

	respondWithJSON(w, http.StatusOK, map[string]string{"message": "Tag deleted successfully"})
}
